/**
 * The shape class
 * Shapes should be created with a set of coordinates and a color for their texture
 */
class tShape
{
  boolean visible;
  boolean hovered;
  int coords[][];
  int position[];
  tTexture textures[];
  int drawTexture;
  // used with drag'n'drop with the mouse
  // relative location on the shape
  int grabLocation[];
  // where the shape was at when the grab was started
  // so that it can "snap back" into place
  int startedGrabAt[];
  // used for generating solarSystems (see types files)
  public int elementID;
  
  /**
   * Creates a shape
   * @param coords should have at least three unique points
   * @param base_color to be used with standard_tTexture_palette()
   * @throws an exception if coords isn't correct
   */
  tShape(int[][] in_coords, color base_color) //throws Exception
  {
    int coordCount = 0;
    
    coords = in_coords;
    textures = standard_tTexture_palette(base_color);
    visible = true;
    hovered = false;
    int tempArr[][] = {{0,0},{0,0}};
    position = tempArr[0];
    startedGrabAt = tempArr[1];
    elementID = -1;
  }
  
  /**
   * updates the shape's "hovered" value based on the mouse's screen position
   * if active, then the shape will move with the mouse
   * also updates the "drawTexture" and "isActive" values
   * @param mousePos the mouse's position on the screen
   * @param active true if the shape is active (will move the shape)
   */
  void update(int[] mousePos, boolean isActive)
  {
    // update drawTexture
    drawTexture = 0;
    if (!visible)
    {
      drawTexture = 3;
    }
    else if (isActive)
    {
      drawTexture = 2;
    }
    else if (this.getPointCollision(mousePos))
    {
      drawTexture = 1;
      hovered = true;
    }
    
    // move the shape
    if (isActive)
    {
      // update the grab location
      if (grabLocation == null)
      {
        grabLocation = new int[2];
        grabLocation[0] = mousePos[0] - position[0];
        grabLocation[1] = mousePos[1] - position[1];
        startedGrabAt[0] = position[0];
        startedGrabAt[1] = position[1];
      }
      position[0] = mousePos[0]-grabLocation[0];
      position[1] = mousePos[1]-grabLocation[1];
      position[0] -= position[0] % globalGridSize;
      position[1] -= position[1] % globalGridSize;
      int collisionColor = globalPalette.getCollisionColor(mousePos);
      if (collisionColor != 0)
      {
        this.changeColor(collisionColor);
        elementID = globalPalette.getCollisionFlavorIndex(mousePos);
        this.setAlpha(200);
      }
      else
      {
        this.setAlpha(255);
      }
    }
    else
    {
      // update the grab location
      if (grabLocation != null)
      {
        this.setAlpha(255);
        if (globalPalette.getCollisionColor(mousePos) != 0)
        {
          position[0] = startedGrabAt[0];
          position[1] = startedGrabAt[1];
        }
        else
        {
//          globalShapeContainer.snap()
        }
      }
      grabLocation = null;
    }
  }
  
  /**
   * sets the color for all textures
   * @param newColor the color to use
   */
  void changeColor(color newColor)
  {
    for (int i = 0; i < textures.length; i++)
    {
      textures[i].changeColor(newColor);
    }
  }
  
  /**
   * sets the transparency for the color
   * should be between 0 and 255
   * @param the alpha value
   */
  void setAlpha(int alphaVal)
  {
    for (int i = 0; i < textures.length; i++)
    {
      textures[i].setAlpha(alphaVal);
    }
  }
  
  /**
   * Draws the shape based off of drawTexture
   * @return the values returned by the texture's doDraw method
   */
  boolean doDraw()
  {
    return textures[drawTexture].doDraw(coords, position);
  }
  
  void setVisibility(boolean is_visible)
  {
    visible = is_visible;
  }
  
  void setPosition(int[] pos)
  {
    position = pos;
  }
  
  /**
   * Get the bounding box of the shape, in the form:
   * [xpos relative to screen, ypos, width of bb, height]
   * @return the bounding box
   */
  int[] getBoundingBox()
  {
    int[] retval = new int[4];
    retval[0] = coords[0][0];
    retval[1] = coords[0][1];
    retval[2] = coords[0][0];
    retval[3] = coords[0][1];
    
    for (int i = 0; i < coords.length; i++)
    {
      retval[0] = min(retval[0], coords[i][0]);
      retval[1] = min(retval[1], coords[i][1]);
      retval[2] = max(retval[2], coords[i][0]);
      retval[3] = max(retval[3], coords[i][1]);
    }
    
    retval[2] -= retval[0];
    retval[3] -= retval[1];
    
    return retval;
  }
  
  boolean getCollision(int[][] coordsA, int[] positionA)
  {
    return checkCollision(coordsA, coords, positionA, position);
  }
  
  boolean getPointCollision(int[] position)
  {
    int origin[] = {0,0};
    int pos[][] = {position};
    return getCollision(pos, origin);
  }
}


